import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
import getdata
def getpre(cityname):
    # 读取CSV文件
    data = getdata.getdf(cityname)
    # print(data.columns)
    # print(data.head())
    df = data.copy()
    df2 = data.copy()
    df['最高气温'] = df['最高气温'].str.replace('℃', '').astype(float)
    df['最低气温'] = df['最低气温'].str.replace('℃', '').astype(float)
    # ...其他预处理步骤...

    df['日期'] = pd.to_datetime(df['日期'])
    df2['日期'] = pd.to_datetime(df2['日期'])
    df['月份'] = df['日期'].dt.month

    # 特征选择和数据规范化
    features = df[['最高气温', '最低气温', '月份']].values
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_features = scaler.fit_transform(features)

    # 创建时间序列数据集
    def create_dataset(data, time_step=1):
        dataX, dataY_high, dataY_low = [], [], []
        for i in range(len(data)-time_step-1):
            a = data[i:(i+time_step), :]
            dataX.append(a)
            dataY_high.append(data[i + time_step, 0]) # 预测下一天的最高气温
            dataY_low.append(data[i + time_step, 1])  # 预测下一天的最低气温
        return np.array(dataX), np.array(dataY_high), np.array(dataY_low)

    time_step = 10
    X, y_high, y_low = create_dataset(scaled_features, time_step)

    # 构建LSTM模型
    model = Sequential()
    model.add(LSTM(50, return_sequences=True, input_shape=(time_step, X.shape[2])))
    model.add(LSTM(50, return_sequences=False))
    model.add(Dense(2))

    model.compile(loss='mean_squared_error', optimizer='adam')

    # 训练模型
    model.fit(X, [y_high, y_low], epochs=10, batch_size=32, verbose=2) 

    # 预测未来的天气
    # 你需要构建一个包含最近时间步长的特征集来进行预测
    # future_predictions = model.predict(future_dataset)
        
    # 获取最近10天的最高气温、最低气温和月份数据
    last_10_days = df.iloc[-10:, :]
    last_10_days_features = last_10_days[['最高气温', '最低气温', '月份']].values

    # 对数据进行规范化处理
    last_10_days_features_scaled = scaler.transform(last_10_days_features)

    # 将规范化后的数据组成一个形状为（1, 10, 3）的三维数组
    future_dataset = np.array([last_10_days_features_scaled])

    #print(future_dataset)

    pre_high = []
    pre_low = []
    last_date = df2['日期'].max()
    future_dates = pd.date_range(start=last_date, periods=31)
    future_dates_list = future_dates.astype(str).tolist()
    del future_dates_list[0]

    for i in range(30):
        future_predictions = model.predict(future_dataset)
        pre_high.append(future_predictions[0][0])
        pre_low.append(future_predictions[0][1])

        # 将预测结果添加到future_dataset的最后一天
        last_day = future_dataset[0][-1]
        new_day = np.array([[future_predictions[0][0], future_predictions[0][1], last_day[2]]])
        new_day = np.expand_dims(new_day, axis=1)  # 添加一个维度，使其形状为（1, 1, 3）
        future_dataset = np.concatenate((future_dataset, new_day), axis=1)
        future_dataset = np.delete(future_dataset, 0, axis=1)

    # 反向转换预测数据
    predicted_values = np.column_stack((pre_high, pre_low, [last_10_days_features[-1, 2]] * len(pre_high)))
    predicted_values = scaler.inverse_transform(predicted_values)

    # 打印反规范化后的预测结果
    # print("预测的最高气温：", predicted_values[:,0])
    # print("预测的最低气温：", predicted_values[:,1])
    print("预测完成")
    #可视化生成
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    # 创建一个图形
    plt.figure(figsize=(10, 6))

    # 绘制最低温度曲线
    plt.plot(future_dates_list,predicted_values[:,0],label='最低温度')
    # 绘制最高温度曲线
    plt.plot(future_dates_list,predicted_values[:,1],label='最高温度')
    # 设置x轴刻度间隔为每隔5天显示一个刻度
    plt.xticks(future_dates_list[::5])
    # 添加图例
    plt.legend()
    # 添加标题和坐标轴标签
    plt.title('最低温度和最高温度随时间变化')
    plt.xlabel('日期')
    plt.ylabel('温度')
    # 保存图像为png格式
    plt.savefig('weatherv3/温度变化图.png')
    

    return predicted_values,future_dates_list

""" if __name__ == "__main__":
    re = getpre('蚌埠')
    print(re) """
